package com.ls.fw.mvc.springmvc.support.interceptor;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.method.HandlerMethod;

import com.ls.fw.mvc.springmvc.support.annotation.RequestProtocol;

/**
 * https/http请求拦截器
 * @author lisheng
 * @date 2016年1月21日 下午8:05:42
 * @version V1.0
 */
public class RequestProtocolInterceptor extends BaseInterceptor {

	private static final int PORT_DIFF = 8443;

	private int port = PORT_DIFF;
    // no need to inject it for now..
    private PathMatcher pathMatcher = new AntPathMatcher();

    private List<String> secureLocations;

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
    	 boolean ret = true; 
		 if (open && handler instanceof HandlerMethod) {
	        Boolean secure = checkSecure((HandlerMethod) handler);
			if(secure != null && secure==Boolean.TRUE 
			   && shouldForceSecure(request.getRequestURI())){
				secure = true;
			}
	        if (secure != null && request.isSecure() != secure) {
				request.getSession(true);
				String q = request.getQueryString();
				if(q != null){
					q = "?" + q;
				}else{
					q = "";
				}
				response.sendRedirect(switchSecure(secure, request.getRequestURL())+q);
                ret = false; 
			}
		 }
        return ret;
    }

	private Boolean checkSecure(HandlerMethod method) {
		RequestProtocol annotation = method
				.getMethodAnnotation(RequestProtocol.class);
		if (annotation == null) {
			annotation = AnnotationUtils.findAnnotation(
					method.getBeanType(), RequestProtocol.class);
		}
		return annotation == null ? null : annotation.secure();
	}
    private boolean shouldForceSecure(String path) {
    	if(secureLocations != null){
	        for (String pattern : secureLocations) {
	            if (pathMatcher.match(pattern, path)) {
	                return true;
	            }
	        }
	    }
        return false;
    }

	private String switchSecure(boolean secure, StringBuffer url) {
		int endSchema = url.indexOf("://");
		url.replace(0, endSchema, secure ? "https" : "http");
		int startPort = url.indexOf(":", endSchema + 3);
		if (startPort != -1) {
			int endPort = url.indexOf("/", startPort);
			url.replace(startPort + 1, endPort, String.valueOf(port));
		}else{//80
			url.insert(url.indexOf("/",url.indexOf("//")+2), ":"+String.valueOf(port));
		}
		return url.toString();
	}
	public static void main(String[] args) {
		StringBuffer sbBuffer = new StringBuffer();
		sbBuffer.append("http://127.0.0.1/test/test/form");
		sbBuffer.insert(sbBuffer.indexOf("/",sbBuffer.indexOf("//")+2), ":8443");
		System.out.println(sbBuffer);
	}
	public PathMatcher getPathMatcher() {
		return this.pathMatcher;
	}

	public void setPathMatcher(PathMatcher pathMatcher) {
		this.pathMatcher = pathMatcher;
	}

	public List<String> getSecureLocations() {
		return this.secureLocations;
	}

	public void setSecureLocations(List<String> secureLocations) {
		this.secureLocations = secureLocations;
	}

	public int getPort() {
		return this.port;
	}

	public void setPort(int port) {
		this.port = port;
	}
}